package Schach;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;

class action{
        public static boolean checkcheck(Figur[][] Feld, String c){
        King king = getKing(Feld, c);
        for (Figur[] reihe : Feld){
            for (Figur figur : reihe){
                if (figur!=null){
                    if (!figur.c.equals(c)){
                        if (figur.moveispossible(Feld, king.xpos, king.ypos) &&
                                figur.allgemeinmoveispossible(Feld, king.xpos, king.ypos)) return true;
                    }
                }
            }
        }
        return false;
    }

    public static King getKing(Figur[][] Feld, String c){
        for (Figur[] reihe : Feld){
            for (Figur figur : reihe){
                if (figur!=null){
                    if (figur.c.equals(c) && (figur.getClass().getName()
                            .substring(7).equals("King"))) return (King) figur;
                }
            }
        }
        return null;
    }

    public static Figur[][] clone(Figur[][] Feld){
        Figur[][] aux = new Figur[8][8];
        for (int i=0; i<8; i++){
            for (int j=0; j<8; j++){
                aux[i][j]=null;
            }
        }

        for (Figur[] reihe : Feld){
            for (Figur figur : reihe){
                if (figur!=null){
                    Figur fig=null;
                    boolean color = figur.c.equals("w")? true : false;
                    if (figur.type.equals(".")){
                        fig = new Bauer(color,figur.xpos,figur.ypos);
                    }
                    if (figur.type.equals("T")){
                        fig = new Turm(color,figur.xpos,figur.ypos);
                    }
                    if (figur.type.equals("S")){
                        fig = new Springer(color,figur.xpos,figur.ypos);
                    }
                    if (figur.type.equals("L")){
                        fig = new Laeufer(color,figur.xpos,figur.ypos);
                    }
                    if (figur.type.equals("D")){
                        fig = new Dame(color,figur.xpos,figur.ypos);
                    }
                    if (figur.type.equals("K")){
                        fig = new King(color,figur.xpos,figur.ypos);
                    }
                    aux[figur.xpos][figur.ypos]= fig;
                }
            }
        }
        return aux;
    }

    public static boolean checkcheckmate(Figur[][] Feld, String c){
        ArrayList<Figur> list = new ArrayList<Figur>();

        Figur[][] aux = clone(Feld);

        for (Figur[] reihe : aux){
            for (Figur figur : reihe){
                if (figur!=null){
                    if (figur.c.equals(c)) list.add(figur);
                }
            }
        }
        for (Figur figur : list){
            for (int i=1; i<9; i++){
                for (int j=1; j<9; j++){
                    aux = clone(Feld);
                    if (figur.move(aux, i, j)){
                        if (!action.checkcheck(aux, c)){
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

}

class Figur{
    protected String c;
    protected int xpos;
    protected int ypos;
    protected String type;
    
    public Figur(){
        this.type=" ";
        this.c = " ";
    }
    public Figur(boolean c, int x, int y, String type){
        this.xpos=x;
        this.ypos=y;
        this.type=type;
        this.c = c? "w" : "s";
    }
    public String getcolor(){
        return c;
    }
    public int getxpos(){
        return xpos;
    }
    public int getypos(){
        return ypos;
    }
    public String gettyp(){
        return type;
    }
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        return false;
    }
    public boolean allgemeinmoveispossible (Figur[][] Feld, int x, int y){
        if( x>7 || x<0 || y>7 || y<0 ) return false;
        if(Feld[x][y]!=null){
            if (Feld[x][y].c.equals(this.c)) return false;
        }
        return true;
    }
    public boolean move(final Figur[][] Feld, final int x, final int y){
        if (allgemeinmoveispossible(Feld,x,y)){
            if(moveispossible(Feld,x,y)){
                Figur aux = Feld[x][y];
                int aux_x = this.xpos;
                int aux_y = this.ypos;
                Feld[x][y]=this;
                Feld[this.xpos][this.ypos] = null; //new x();
                this.xpos=x;
                this.ypos=y;
                if (!action.checkcheck(Feld, this.c)){
                    final Figur figur = Feld[x][y];
                    if (figur.getClass().getName().substring(7).equals("Bauer")){
                        if ((figur.c.equals("w") && y==7)||(figur.c.equals("s") && y==0)){
                            final JFrame frameEvolve = new JFrame();
                            frameEvolve.setName("evolve Bauer");
                            frameEvolve.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                            frameEvolve.setBounds(200, 200, 1000, 200);
                            
                            final JButton dame = new JButton("Dame");
                            dame.setSize(150, 100);
                            dame.setLocation(50, 50);
                            dame.addActionListener( new ActionListener() {
                                @Override public void actionPerformed( ActionEvent e ) {
                                    if (figur.c.equals("w")) Feld[x][y] = new Dame(true, x, y);
                                    else Feld[x][y] = new Dame(false, x, y);
                                    frameEvolve.setVisible(false);
                                    gui.aufstellung(Feld, gui.spielfeld);
                                }
                            });
                            
                            final JButton turm = new JButton("Turm");
                            turm.setSize(150, 100);
                            turm.setLocation(250, 50);
                            turm.addActionListener( new ActionListener() {
                                @Override public void actionPerformed( ActionEvent e ) {
                                    if (figur.c.equals("w")) Feld[x][y] = new Turm(true, x, y);
                                    else Feld[x][y] = new Turm(false, x, y);
                                    frameEvolve.setVisible(false);
                                    gui.aufstellung(Feld, gui.spielfeld);
                                }
                            });

                            final JButton springer = new JButton("Springer");
                            springer.setSize(150, 100);
                            springer.setLocation(450, 50);
                            springer.addActionListener( new ActionListener() {
                                @Override public void actionPerformed( ActionEvent e ) {
                                    if (figur.c.equals("w")) Feld[x][y] = new Springer(true, x, y);
                                    else Feld[x][y] = new Springer(false, x, y);
                                    frameEvolve.setVisible(false);
                                    gui.aufstellung(Feld, gui.spielfeld);
                                }
                            });
                            
                            final JButton laeufer = new JButton("Läufer");
                            laeufer.setSize(150, 100);
                            laeufer.setLocation(650, 50);
                            laeufer.addActionListener( new ActionListener() {
                                @Override public void actionPerformed( ActionEvent e ) {
                                    if (figur.c.equals("w")) Feld[x][y] = new Laeufer(true, x, y);
                                    else Feld[x][y] = new Laeufer(false, x, y);
                                    frameEvolve.setVisible(false);
                                    gui.aufstellung(Feld, gui.spielfeld);
                                }
                            });
                            
                            frameEvolve.add(dame);
                            frameEvolve.add(turm);
                            frameEvolve.add(springer);
                            frameEvolve.add(laeufer);

                            JButton bg = new JButton();
                            bg.setVisible(false);
                            frameEvolve.add(bg);

                            frameEvolve.setVisible(true);
                        }
                    }
                    return true;
                }
                else{
                    this.xpos = aux_x;
                    this.ypos = aux_y;
                    Feld[this.xpos][this.ypos] = this;
                    Feld[x][y] = aux;
                    System.out.println("Move not possible!!! Schach.");
                    return false;
                }
            }else{
                //System.out.println("Move not possible!!! Etwas im Weg oder falsche Bewegung der Figur.");
                return false;
            }
        }else{
            //System.out.println("Move not possible!!! Wert außerhalb des Feldes oder Position von eigener Figur besetzt");
            return false;
        }
    }


    public int abs(int a, int b){
        return a-b>0 ? a-b : b-a;
    }

}

/**class x extends Figur{
    public x(){
        this.type="X";
        this.c=" ";
    }
}
 */

class Bauer extends Figur{
    public Bauer(boolean c, int x, int y){
        super(c,x,y,".");
    }

    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        if(this.moveispossible2(Feld,x,y)) return true;
        return false;
    }

    public boolean moveispossible2(Figur[][] Feld, int x, int y){
        if(this.c.equals("w")){ //weiss

            if((this.xpos == x) && (this.ypos + 1 == y) && (Feld[x][y] == null)) return true;

            if(Feld[x][y]!=null){
                if((this.xpos+1==x || this.xpos-1==x)
                    && this.ypos+1==y && !Feld[x][y].c.equals(this.c)) return true;
            }

            if((this.ypos == 1) && (this.xpos == x) && ( 3 == y ) && (Feld[x][y] == null)
                                                    && (Feld[x][y-1] == null))return true;
            
        }else{  //schwarz

            if((this.xpos == x) && (this.ypos - 1 == y) && (Feld[x][y] == null))return true;

            if(Feld[x][y]!=null){
                if((this.xpos+1==x || this.xpos-1==x)
                    && this.ypos-1==y && !Feld[x][y].c.equals(this.c))return true;
            }

            if((this.ypos == 6) && (this.xpos == x) && ( 4 == y ) && ( Feld[x][y] == null)
                                                    && (Feld[x][y+1] == null))return true;
        }
        return false;
    }
}

class Turm extends Figur{
    boolean moved = false;
    public Turm(boolean c, int x, int y){
        super(c,x,y,"T");
    }
    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        int aux;
        
        if((this.xpos == x) && (this.ypos != y)){
            aux = this.ypos;
            while(aux != y){
                if (Feld[x][aux]!=null && Feld[x][aux]!=this) return false;
                aux = aux<y ? aux+1 : aux-1;
            }
            return true;
        }
        if((this.xpos != x) && (this.ypos == y)){
            aux = this.xpos;
            while(aux != x){
                if (Feld[aux][y]!=null && Feld[aux][y]!=this) return false;
                aux = aux<x ? aux+1 : aux-1;
            }
            return true;
        }
        return false;
    }
}

class Springer extends Figur{
    public Springer(boolean c, int x, int y){
        super(c,x,y,"S");
    }
    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){

        if (    (x==this.xpos+1 && y==this.ypos+2) ||
                (x==this.xpos+1 && y==this.ypos-2) ||
                (x==this.xpos-1 && y==this.ypos+2) ||
                (x==this.xpos-1 && y==this.ypos-2) ||
                (x==this.xpos+2 && y==this.ypos+1) ||
                (x==this.xpos+2 && y==this.ypos-1) ||
                (x==this.xpos-2 && y==this.ypos+1) ||
                (x==this.xpos-2 && y==this.ypos-1)  )  return true;
        return false;
    }
}

class Laeufer extends Figur{
    public Laeufer(boolean c, int x, int y){
        super(c,x,y,"L");
    }
    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        int aux = this.xpos;
        int xhelp = 1;
        int auy = this.ypos;
        int yhelp = 1;
        if ((abs(this.xpos, x)!=abs(this.ypos, y)) || this.xpos==x ) return false;

        if(x<this.xpos) xhelp=-1;
        if(y<this.ypos) yhelp=-1;

            while(aux != x){
                if (Feld[aux][auy]!=null && Feld[aux][auy]!=this) return false;
                aux = aux + xhelp;
                auy = auy + yhelp;
            }
            return true;
    }
}

class Dame extends Figur{
    public Dame(){
    }
    public Dame(boolean c, int x, int y){
        super(c,x,y,"D");
    }
    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        if( laeufer(Feld,x,y) || turm(Feld,x,y) ) return true;
        return false;
    }

    public boolean laeufer(Figur[][] Feld, int x, int y){
        int aux = this.xpos;
        int xhelp = 1;
        int auy = this.ypos;
        int yhelp = 1;
        if ((abs(this.xpos, x)!=abs(this.ypos, y)) || this.xpos==x ) return false;

        if(x<this.xpos) xhelp=-1;
        if(y<this.ypos) yhelp=-1;

            while(aux != x){
                if (Feld[aux][auy]!=null && Feld[aux][auy]!=this) return false;
                aux = aux + xhelp;
                auy = auy + yhelp;
            }
            return true;
    }
    
    public boolean turm(Figur[][] Feld, int x, int y){
        int aux;

        if((this.xpos == x) && (this.ypos != y)){
            aux = this.ypos;
            while(aux != y){
                if (Feld[x][aux]!=null && Feld[x][aux]!=this) return false;
                aux = aux<y ? aux+1 : aux-1;
            }
            return true;
        }
        if((this.xpos != x) && (this.ypos == y)){
            aux = this.xpos;
            while(aux != x){
                if (Feld[aux][y]!=null && Feld[aux][y]!=this) return false;
                aux = aux<x ? aux+1 : aux-1;
            }
            return true;
        }
        return false;
    }
}


class King extends Figur{
    boolean moved = false;
    public King(boolean c, int x, int y){
        super(c,x,y,"K");
    }
    @Override
    public boolean moveispossible(Figur[][] Feld, int x, int y){
        if (rochade(Feld,x,y)) return true;
        if(abs(this.xpos,x)>1 || abs(this.ypos,y)>1) return false;
        if(Feld[x][y]==null || !Feld[x][y].c.equals(this.c)) return true;
        return false;
    }

    public boolean rochade(Figur[][]Feld, int x, int y){
        if (this.c.equals("w")){
            if (x==6 && y==0 && Feld[7][0]!=null){
                if (Feld[7][0].type.equals("T")){
                Turm turm = (Turm) Feld[7][0];
                if (!this.moved && !turm.moved && Feld[5][0]==null && Feld[6][0]==null &&
                        !action.checkcheck(Feld, this.c)){
                    Feld[5][0] = turm;
                    turm.xpos=5;
                    turm.ypos=0;
                    Feld[7][0] = null;
                    return true;
                }
                }
            }
            if (x==2 && y==0 && Feld[0][0]!=null){
                if (Feld[0][0].type.equals("T")){
                Turm turm = (Turm) Feld[0][0];
                if (!this.moved && !turm.moved && Feld[1][0]==null && Feld[2][0]==null &&
                        !action.checkcheck(Feld, this.c)){
                    Feld[3][0] = turm;
                    turm.xpos=3;
                    turm.ypos=0;
                    Feld[0][0] = null;
                    return true;
                }
                }
            }
        }else{
            if (x==6 && y==7 && Feld[7][7]!=null){
                if (Feld[7][7].type.equals("T")){
                Turm turm = (Turm) Feld[7][7];
                if (!this.moved && !turm.moved && Feld[5][7]==null && Feld[6][7]==null &&
                        !action.checkcheck(Feld, this.c)){
                    Feld[5][7] = turm;
                    turm.xpos=5;
                    turm.ypos=7;
                    Feld[7][7] = null;
                    return true;
                }
                }
            }
            if (x==2 && y==7 && Feld[0][7]!=null){
                if (Feld[0][7].type.equals("T")){
                Turm turm = (Turm) Feld[0][7];
                if (!this.moved && !turm.moved && Feld[1][7]==null && Feld[2][7]==null &&
                        !action.checkcheck(Feld, this.c)){
                    Feld[3][7] = turm;
                    turm.xpos=3;
                    turm.ypos=7;
                    Feld[0][7] = null;
                    return true;
                }
                }
            }
        }
        return false;
    }

}


public class Main {

    static Figur[][] Feld = new Figur[8][8];

    public static void printfield(){
        System.out.println("|--------------------------------------|");

        int k;
        int i=0;
        int j=7;
        while(j>=0){
            k=j+1;
            System.out.print("|| " + k + " |");
            i=0;
            while (i<7){
                if (Feld[i][j]!=null){
                    System.out.print("| " + Feld[i][j].gettyp() + Feld[i][j].c);
                }else{
                    System.out.print("|   ");
                }
                i++;
            }
            if (Feld[i][j]!=null){
                System.out.println("| " + Feld[i][j].gettyp() + Feld[i][j].c + "||");
            }else{
                System.out.println("|   ||");
            }
            System.out.println("|--------------------------------------|");
            j--;
        }
        System.out.println("||   || 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 ||");
        System.out.println("|--------------------------------------|");

        //finddummy();
    }

    /**public static void finddummy(){
        String a="";
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                if (Feld[i][j]!=null) a = Feld[i][j].getClass().toString();
                if (a.equals("class Schach.x")){
                    Feld[i][j]=null;
                    return;
                }
            }
        }
    }
     */

    public static void aufstellung(){
        for (int i=0; i<8; i++){
            for (int j=0; j<8; j++){
                Feld[i][j] = null;
            }
        }
        for (int i=0; i<8; i++){
            Feld[i][1] = new Bauer(true, i, 1);
            Feld[i][6] = new Bauer(false, i, 6);
        }
            Feld[0][0] = new Turm(true, 0, 0);
            Feld[7][0] = new Turm(true, 7, 0);
            Feld[0][7] = new Turm(false, 0, 7);
            Feld[7][7] = new Turm(false, 7, 7);
            Feld[1][0] = new Springer(true, 1, 0);
            Feld[6][0] = new Springer(true, 6, 0);
            Feld[1][7] = new Springer(false, 1, 7);
            Feld[6][7] = new Springer(false, 6, 7);
            Feld[2][0] = new Laeufer(true, 2, 0);
            Feld[5][0] = new Laeufer(true, 5, 0);
            Feld[2][7] = new Laeufer(false, 2, 7);
            Feld[5][7] = new Laeufer(false, 5, 7);
            Feld[3][0] = new Dame(true, 3, 0);
            Feld[4][0] = new King(true, 4, 0);
            Feld[3][7] = new Dame(false, 3, 7);
            Feld[4][7] = new King(false, 4, 7);
    }

    public static int[] ask(String turn){
        String t = javax.swing.JOptionPane.showInputDialog(turn + "Spalte,Reihe,Spalte,Reihe?:");
        String[] array = t.split(",");
        if (t==null){

        }
        int[] a ={Integer.parseInt(array[0]),
            Integer.parseInt(array[1]),
            Integer.parseInt(array[2]),
            Integer.parseInt(array[3])};

        return a;
    }

    public static boolean move(int x1, int y1, int x2, int y2, String turn){
        if (Feld[x1-1][y1-1]!=null) System.out.println("Moving: " + Feld[x1-1][y1-1].type + x1 + y1 + "-" + x2 + y2);

        x1--;y1--;x2--;y2--;

        if (Feld[x1][y1]!=null){
            if (Feld[x1][y1].c.equals(turn)){
                return Feld[x1][y1].move(Feld, x2, y2);
            }else{
                System.out.println(turn + " ist am Zug");
                return false;
            }
        }else{
            System.out.println("Feld ist leer!!");
            return false;
        }

        
    }

    public static void main(String[] args) {
        int[] move;
        String turn ="w";
        String x = turn.equals("w")? "Weiss: " : "Schwarz: ";

        aufstellung();
        printfield();
        gui.start();
/**
        boolean play = true;
        while (play){
            move = ask(x);
            System.out.println(move[0] + " " + move[1] + " " +  move[2] + " " +  move[3]);
            if (move(move[0],move[1],move[2],move[3], turn)) turn = turn.equals("w")? "s" : "w";
            printfield();
            x = turn.equals("w")? "Weiss: " : "Schwarz: ";
        }
 */
    }
}